package com.hjj.springboot.service;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hjj.springboot.config.BaiduAiOcrConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class BaiduAiOcrService {
    private final BaiduAiOcrConfig config;
    private String accessToken;
    private long tokenExpireTime;

    public BaiduAiOcrService(BaiduAiOcrConfig config) {
        this.config = config;
    }

    // 获取Access Token（带缓存）
    private void refreshAccessToken() throws IOException {
        String url = String.format("%s?grant_type=client_credentials&client_id=%s&client_secret=%s",
                config.getAccessTokenUrl(), config.getApiKey(), config.getSecretKey());

        try (CloseableHttpClient client = HttpClients.createDefault()) {
            HttpGet request = new HttpGet(url);

            try (CloseableHttpResponse response = client.execute(request)) {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode != 200) {
                    throw new IOException("获取文字识别Token失败，状态码: " + statusCode);
                }

                String json = EntityUtils.toString(response.getEntity());
                JsonNode node = new ObjectMapper().readTree(json);

                if (node.has("error")) {
                    throw new IOException("百度文字识别认证错误: "
                            + node.get("error_description").asText());
                }

                this.accessToken = node.get("access_token").asText();
                this.tokenExpireTime = System.currentTimeMillis()
                        + node.get("expires_in").asLong() * 1000;
                log.info("成功获取百度文字识别AI AccessToken，有效期至: {}", new Date(tokenExpireTime));
            }
        }
    }

    public String detectOrc(MultipartFile imageFile) throws IOException {
        if (accessToken == null || System.currentTimeMillis() >= tokenExpireTime) {
            refreshAccessToken();
        }

        String imageBase64 = Base64.getEncoder().encodeToString(imageFile.getBytes());
        String requestUrl = config.getGeneralUrl() + "?access_token=" + accessToken;

        HttpPost post = new HttpPost(requestUrl);
        post.addHeader("Content-Type", "application/x-www-form-urlencoded");

        List<NameValuePair> params = new ArrayList<>();
        params.add(new BasicNameValuePair("image", imageBase64));
        post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));

        try (CloseableHttpClient client = HttpClients.createDefault();
             CloseableHttpResponse response = client.execute(post)) {

            if (response.getStatusLine().getStatusCode() != 200) {
                throw new IOException("文字识别请求失败，状态码: "
                        + response.getStatusLine().getStatusCode());
            }

            return EntityUtils.toString(response.getEntity());
        }
    }
}

